<?php

namespace App\Http\Controllers;

use App\Models\ResourceEbookChapterInfo;
use App\Models\ResourceEbookInfo;
use App\Models\ResourceTotal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Intervention\Image\ImageManagerStatic as Image;

/**
 * 文件上传类（上传电子书）
 */
class UploadsFileEbookController extends Controller
{

    //允许文件上传的key
    protected $allow_file_name_arr = [
        'ebook'
    ];
    //需要生成缩略图的key
    protected $need_thumb_file_name_arr = [
        'img',
    ];
    /**
     * 定义图片上传公共方法           (单文件与多文件都可以(多文件上传不生成缩略图)  暂不支持多文件上传)
     * @param file 文件名   根据每个方法要求不同，传不同名称   默认 ebook
     *                     固定参数   img  前台活动报名，上传图片   不需生成缩略图   最大1M
     *
     *
     *@param is_forever 是否是永久     1  是   2不是
     *@param copyright_end_time 版权到期时间 年月日
     *@param type_id 分类id
     */
    public function commonUpload(Request $request)
    {
        //删除所有临时文件
        $this->delAllTempFile();

        if (empty($request->is_forever) || ($request->is_forever == 2 && empty($request->copyright_end_time))) {
            return (['code' => 404, 'msg' => '版权信息不能为空', 'data' => '']);
        }

        $file_name = array_keys($_FILES);
        //   dd([request()->file($file_name[0])->getMimeType(),request()->file($file_name[0])->getClientMimeType(),request()->file($file_name[0])->getClientOriginalExtension()]);

        if (empty($file_name))  return response()->json(['code' => 201, 'msg' => '上传文件不能为空']);

        if (!in_array($file_name[0], $this->allow_file_name_arr)) return response()->json(['code' => 201, 'msg' => '上传文件名错误']);

        $file_size = $_FILES[$file_name[0]]['size']; //获取上传文件大小

        //验证文件类型和大小
        $file_validate = $this->fileValidate($request, $file_name[0]);
        if ($file_validate !== true) {
            return response()->json(['code' => 201, 'msg' => $file_validate]);
        }

        $foldername = $file_name[0] . '/' . date('Y-m-d'); //$file_name.'/'.date('Y-m-d')  存放路径，按日志存储
        $file = $request->file($file_name[0])->store($foldername);
        $file_addr = public_path('uploads') . '/' . $file; //图片地址

        if ($file) {
            $file_name = explode('/', $file_addr);
            $file_name = array_pop($file_name);
            $file_relative_path = explode('.', $file); //获取文件相对路径
            $file_path = str_replace($file_name, '', $file_addr); //获取图片路径
            //  $file_name = explode('.', $file_name);
            //  $file_name = $file_name[0]; //获取图片名称
            try {
                $ebook_info = $this->getEpubInfo($file_path, $file_name, $file_relative_path[0]);
                $ebook_info['postfix'] = end($file_relative_path);
                $ebook_info['path'] = $file;
                $ebook_info['size'] = $file_size; //获取上传文件大小
                //添加电子书
                $ebook_id = $this->addEbook($ebook_info, $file_addr, $request->is_forever, $request->copyright_end_time, $request->type_id);

                //添加电子书章节表
                $this->chapterInfoAdd($ebook_info['chapter_info'], $ebook_id);
            } catch (\Exception $e) {
                return (['code' => 404, 'msg' => $e->getMessage() . $e->getFile() . $e->getLine(), 'data' => '']);
            }
            return (['code' => 200, 'msg' => '上传成功', 'content' => $ebook_info]);
        } else {
            return (['code' => 404, 'msg' => '未找到资源', 'data' => '']);
        }
    }


    /**
     * 获取图片封面（缩略图）
     * @param $file_addr 图片路径  ,数据库存放路径
     * @param $file 原图片返回到前端的地址
     */
    public function getEpubInfo($file_path, $filename, $file_relative_path)
    {
        $ebookAnalysisObj = new EbookAnalysisController();
        $get_zip_file = $ebookAnalysisObj->getZipOriginalsize($filename, $file_path);
        if ($get_zip_file) {
            //获取封面图片 ISBN 和  出版时间
            $cover_name_isbn_time = $ebookAnalysisObj->getEbookCoverImg($file_path . $filename);

            $data["img"] = isset($cover_name_isbn_time['cover_img']) ? $file_relative_path . '/' . $cover_name_isbn_time['cover_img'] : '';
            $data["isbn"] = isset($cover_name_isbn_time['isbn']) ? $cover_name_isbn_time['isbn'] : '';
            $data["pre_time"] = isset($cover_name_isbn_time['date']) ? $cover_name_isbn_time['date'] : '';
            $data["title"] = isset($cover_name_isbn_time['title']) ? $cover_name_isbn_time['title'] : '';
            $data["author"] = isset($cover_name_isbn_time['author']) ? $cover_name_isbn_time['author'] : '';

            //获取电子书名称 作者 及内容
            $news_path = explode('.', $filename);
            $file_name = reset($news_path);
            $content = $ebookAnalysisObj->getContent($file_path . $filename, $file_name);
            $data['chapter_info'] = $content['content'];
            //如果之前没获取到作者 或标题
            $data['title'] = empty($data['title']) ? $content['ebook_filename'] : $data['title'];
            $data['author'] = empty($data['author']) ? $content['ebook_author'] : $data['author'];

            if (empty($data['author']) || $data['author'] == ".") {
                $data['author'] = '佚名';
            }
        } else {
            throw new \Exception('文件解压失败');
        }
        return $data;
    }

    /**
     * 添加电子书
     * @param $data 电子书数据
     */
    public function addEbook($data, $ebook_file_addr, $is_forever = null, $copyright_end_time = null, $type_id = null)
    {
        $ebookInfoModel = new ResourceEbookInfo();
        //用书名、作者、ISBN去查询是是否已有此电子书
        $ebook_id = $ebookInfoModel->where(['isbn' => $data["isbn"], 'title' => $data['title'], 'author' => $data['author']])->where('is_del', 1)->value('id');

        if ($ebook_id) {
            //如果之前就存在记录，删除现在的记录
            $this->delEbookIInfo($ebook_file_addr);
            throw new \Exception('相同文件不能重复添加');
        }

        unset($data['chapter_info']);
        $data['guid'] = get_guid();
        $data['type_id'] = $type_id;
        $data['is_forever'] = $is_forever;
        $data['copyright_end_time'] = $copyright_end_time;
        $ebookInfoModel->add($data);

        //添加到总记录表
        $resourceTotalModel = new ResourceTotal();
        $data['big_type_id'] = 1;
        $resourceTotalModel->addData($data);

        return $ebookInfoModel->id;
    }

    /**
     * 添加电子书章节
     * $ebook_id  电子书id
     * $superior_id   章节上级id
     */
    public function chapterInfoAdd($content, $ebook_id, $superior_id = 0)
    {
        foreach ($content as $key => $val) {
            $ebookChapterInfoModel = new ResourceEbookChapterInfo();

            $data = array(
                "ebook_id" => $ebook_id,
                "chapter_name" => $val["navLabel"],
                "chapter_src" => $val["src"],
                "chapter_id" => $val["id"],
                "sort" => $val["playOrder"],
                "pid" => $superior_id,
            );
            $ebookChapterInfoModel->add($data);
            $self_id = $ebookChapterInfoModel->id;
            //确定path的值
            if ($superior_id == 0) {
                $path = $self_id;
            } else {
                $path = $ebookChapterInfoModel->where("id", $superior_id)->value("path") . '-' . $self_id;
            }

            //权限表存在的字段，现在还无法满足要求，
            //只有先插入现有的字段，插入成功，返回，最后插入的
            //主键id，在根据这个主键id，进行修改

            $level = substr_count($path, "-");
            $ebookChapterInfoModel->where('id', $self_id)->update([
                "path" => $path,
                "level" => $level
            ]);

            //判断数组中是否还有数组,如果有继续添加   $val['chicd'][0]有可能不存在
            if (array_key_exists('child', $val) && isset($val['child'][0])) {
                //证明还是一个数组
                $data[$key]['child'] = $this->chapterInfoAdd($val['child'], $ebook_id, $self_id);
            }
        }
    }


    /**
     * 删除电子书信息
     * @param $oldEbookInfo
     */
    public function delEbookIInfo($ebook_file_addr)
    {
        @unlink($ebook_file_addr); //删除源文件.epub文件
        $news_path = explode(".", $ebook_file_addr);
        $dir_path = reset($news_path);
        delete_file_and_dir($dir_path); //递归删除源文件夹
    }



    /**
     * 文件验证
     */
    public function fileValidate($request, $file = 'file')
    {
        $file_type = $this->getFileTypeAndSize($file);
        // dump($request->file());
        // dump($request->$file->extension());

        //获取文件真实后缀名 $request->$file->extension()
        $validator = Validator::make($request->file(), [
            $file => 'required|file|max:' . $file_type['size'] . '|mimes:' . $file_type['ext'],
        ], [
            //验证是否存在文件
            $file . '.required' => '文件不能为空',
            //验证是否为文件
            $file . '.file' => '请确认你的文件格式',
            //验证文件上传大小
            $file . '.max' => '文件大小不符合要求',
            //验证上传文件格式
            $file . '.mimes' => '请确认上传文件后缀' . $file_type['ext'],
        ]);
        if ($validator->fails()) { //如果有错误
            // return $validator->errors(); //返回得到错误
            return join('|', $validator->errors()->toArray()[$file]); //获取所有的错误，用 | 拼接
        }

        return true;
    }

    /**
     * 根据文件名，定义上传允许的后缀 和 文件大小
     * https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types   mimes mimetypes  对照表
     */
    public function getFileTypeAndSize($file_name)
    {
        switch ($file_name) {
            case 'production':
                $file_type = ['size' => 10 * 1024, 'ext' => 'jpg,png,jpeg']; //10M   size 是以 kb为单位
                break;
            case 'book_img':
                $file_type = ['size' => 2 * 1024, 'ext' => 'jpg,png,jpeg'];
                break;
            case 'resource_img':
                $file_type = ['size' => 2 * 1024, 'ext' => 'jpg,png,jpeg'];
                break;
            case 'production_cover':
                $file_type = ['size' => 0.5 * 1024, 'ext' => 'jpg,png,jpeg']; //0.5M   size 是以 kb为单位
                break;
            case 'video':
                $file_type = ['size' => 200 * 1024, 'ext' => 'mp4,mov']; //200M
                break;
            case 'voice':
                $file_type = ['size' => 10 * 1024, 'ext' => 'mp3,m4a']; //10M
                break;
            case 'ebook':
                $file_type = ['size' => 100 * 1024, 'ext' => 'epub,zip']; //100M    //apk文件被识别成了 zip文件
                break;
            case 'screen_log':
                $file_type = ['size' => 3 * 1024, 'ext' => 'txt']; //3M
                break;
            case 'doc_file':
                $file_type = ['size' => 3 * 1024, 'ext' => 'xls,xlsx,doc,docx,zip']; //3M  //xlsx文件有时会被识别成了 zip文件，有时正常， docx文件有时会被识别成了 zip文件，有时正常，   doc，xls 则还是  xls格式
                break;
            case 'ui_resource':
                $file_type = ['size' => 5 * 1024, 'ext' => 'zip']; //500KB  //xlsx文件有时会被识别成了 zip文件，有时正常， docx文件有时会被识别成了 zip文件，有时正常，   doc，xls 则还是  xls格式
                break;
            default:
                $file_type = ['size' => 1 * 1024, 'ext' => 'jpg,png,jpeg'];
                break;
        }
        return $file_type;
    }
}
